package biz

import (
	"context"
	"errors"
)

// CategoryRepo 分类仓储接口，定义分类相关的数据操作方法
// 包括创建、更新、查询、删除、唯一性校验、引用校验等
type CategoryRepo interface {
	Create(ctx context.Context, c *Category) (*Category, error)             // 创建分类
	Update(ctx context.Context, c *Category) (*Category, error)             // 更新分类
	Get(ctx context.Context, id int64) (*Category, error)                   // 查询分类详情
	List(ctx context.Context, page, pageSize int) ([]*Category, int, error) // 分页查询分类列表
	Delete(ctx context.Context, id int64) error                             // 删除分类
	NameExists(ctx context.Context, name string) bool                       // 校验分类名唯一性
	HasProduct(ctx context.Context, categoryId int64) bool                  // 校验分类是否被商品引用
}

// CategoryUsecase 分类用例层，封装分类相关业务逻辑
type CategoryUsecase struct {
	repo CategoryRepo
}

// NewCategoryUsecase 创建分类用例实例
func NewCategoryUsecase(repo CategoryRepo) *CategoryUsecase {
	return &CategoryUsecase{repo: repo}
}

// Create 创建分类
func (uc *CategoryUsecase) Create(ctx context.Context, c *Category) (*Category, error) {
	// 数据验证
	if err := uc.validateCategory(c); err != nil {
		return nil, err
	}

	// 检查分类名唯一性
	if uc.repo.NameExists(ctx, c.Name) {
		return nil, errors.New("分类名称已存在")
	}

	return uc.repo.Create(ctx, c)
}

// Update 更新分类
func (uc *CategoryUsecase) Update(ctx context.Context, c *Category) (*Category, error) {
	// 数据验证
	if err := uc.validateCategory(c); err != nil {
		return nil, err
	}

	// 检查分类是否存在
	existing, err := uc.repo.Get(ctx, c.ID)
	if err != nil {
		return nil, errors.New("分类不存在")
	}

	// 如果名称变更，检查唯一性
	if existing.Name != c.Name && uc.repo.NameExists(ctx, c.Name) {
		return nil, errors.New("分类名称已存在")
	}

	return uc.repo.Update(ctx, c)
}

// Get 查询分类详情
func (uc *CategoryUsecase) Get(ctx context.Context, id int64) (*Category, error) {
	if id <= 0 {
		return nil, errors.New("分类ID无效")
	}
	return uc.repo.Get(ctx, id)
}

// List 分页查询分类列表
func (uc *CategoryUsecase) List(ctx context.Context, page, pageSize int) ([]*Category, int, error) {
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 || pageSize > 100 {
		pageSize = 20
	}
	return uc.repo.List(ctx, page, pageSize)
}

// Delete 删除分类
func (uc *CategoryUsecase) Delete(ctx context.Context, id int64) error {
	if id <= 0 {
		return errors.New("分类ID无效")
	}

	// 检查分类是否存在
	_, err := uc.repo.Get(ctx, id)
	if err != nil {
		return errors.New("分类不存在")
	}

	// 检查是否被商品引用
	if uc.repo.HasProduct(ctx, id) {
		return errors.New("分类正在被商品使用，无法删除")
	}

	return uc.repo.Delete(ctx, id)
}

// validateCategory 验证分类数据
func (uc *CategoryUsecase) validateCategory(c *Category) error {
	if c.Name == "" {
		return errors.New("分类名称不能为空")
	}
	if len(c.Name) > 50 {
		return errors.New("分类名称长度不能超过50个字符")
	}
	return nil
}

// NameExists 校验分类名唯一性
func (uc *CategoryUsecase) NameExists(ctx context.Context, name string) bool {
	return uc.repo.NameExists(ctx, name)
}

// HasProduct 校验分类是否被商品引用
func (uc *CategoryUsecase) HasProduct(ctx context.Context, categoryId int64) bool {
	return uc.repo.HasProduct(ctx, categoryId)
}
